﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Web.UI.WebControls;
using BussinessLogicTecnoPez.Produccion.Clasificacion_e_Incubacion;
using Tecnopez.Globals;
using WebChart;
using WebUtils.Controls;

public partial class Modules_ClasificacionIncubacion_consultarSeguimientoDeEstanque : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        GenericMasterPage master = (GenericMasterPage)this.Master;
        master.Imagen = "../Styles/Icons/wordprocessing.png";
        master.Titulo = "Seguimiento estadístico de estanque.";
        if (!IsPostBack)
        {

            multiPrincipal.SetActiveView(viewFiltros);
        }
        popEstanque.ObjType = typeof(Estanque);
    }
    protected void cboClasificaciones_SelectedIndexChanged(object sender, EventArgs e)
    {
        modoReporte();
    }

    private DateTime fechaDesde
    {
        set
        {
            ViewState["fechaDesde"] = value;
        }
        get
        {
            return Convert.ToDateTime(ViewState["fechaDesde"]);

        }
    }

    private DateTime fechaHasta
    {
        set
        {
            ViewState["fechaHasta"] = value;
        }
        get
        {
            return Convert.ToDateTime(ViewState["fechaHasta"]);
        }
    }

    private Estanque estanque
    {
        set
        {
            ViewState["estanque"] = value;
        }
        get
        {
            return ViewState["estanque"] as Estanque;
        }
    }


    protected void btnGenerarReporte_Click(object sender, EventArgs e)
    {
        DateTime _fechaDesde, _fechaHasta;
        if (!DateTime.TryParse(dtDesde.Text, out _fechaDesde))
        {
            Functions.MessageBox("La fecha desde no es válida.", this);
            return;
        }
        if (!DateTime.TryParse(dtHasta.Text, out _fechaHasta))
        {
            Functions.MessageBox("La fecha hasta no es válida.", this);
            return;
        }
        if (popEstanque.ItemSelected == null)
        {
            Functions.MessageBox("Debe seleccionar un estanque.", this);
            return;
        }
        this.estanque = popEstanque.ItemSelected as Estanque;
        this.fechaHasta = _fechaHasta;
        this.fechaDesde = _fechaDesde;
        multiPrincipal.SetActiveView(viewResultados);
        llenarComboClasificaciones();
        lblFechaDesde.Text = fechaDesde.ToShortDateString();
        lblFechaHasta.Text = fechaHasta.ToShortDateString();
        if (cboClasificaciones.Items.Count > 0)
        {
            cboClasificaciones.SelectedIndex = cboClasificaciones.Items.Count - 1;

        }
        modoReporte();
    }

    private void modoReporte()
    {
        if (cboClasificaciones.SelectedIndex == -1)
        {
            Functions.MessageBox("No se han recoletado datos de clasificaciones para este estanque.", this);
            return;
        }

        Int32 idClasificacionSeleccionada = Convert.ToInt32(cboClasificaciones.SelectedValue);

        if (seleccionarClasificacion(idClasificacionSeleccionada))
        {
            List<Clasificacion> clasificaciones = Clasificacion.obtenerFiltradas(estanque.idEstanque, fechaDesde, fechaHasta);
            llenarGraficoDeTamanio(clasificaciones);
            llenarGraficoDePeso(clasificaciones);
            llenarGraficoDeEvolucionDeTamanio(clasificaciones);
        }

    }


    private class punto : IComparable
    {
        public DateTime fecha;
        public float valor;

        #region Miembros de IComparable

        public int CompareTo(object obj)
        {
            punto acomparar = obj as punto;
            return this.fecha.CompareTo(acomparar.fecha);
        }

        #endregion
    }

    private void llenarGraficoDeEvolucionDeTamanio(List<Clasificacion> clasificaciones)
    {

        ConfigureColors(chartEvolucion);
        Dictionary<string, ColumnChart> graficoApilado = new Dictionary<string, ColumnChart>();
        int alpha = 0;
        Dictionary<string, List<punto>> graficos = new Dictionary<string, List<punto>>();


        foreach (Clasificacion clasif in clasificaciones)
        {
            foreach (detalleClasificacion det in clasif.detalle)
            {
                punto p = new punto();
                p.fecha = clasif.fecha;
                p.valor = (float)(det.proporcion * clasif.totalEnEstanque);
                List<punto> puntos;
                if (graficos.TryGetValue(det.loteDeOva.Codigo, out puntos))
                {
                    puntos.Add(p);
                }
                else
                {
                    puntos = new List<punto>();
                    puntos.Add(p);
                    graficos.Add(det.loteDeOva.Codigo, puntos);
                }
            }
        }

        foreach (KeyValuePair<string, List<punto>> parComparador in graficos)
        {
            foreach (KeyValuePair<string, List<punto>> parAComparar in graficos)
            {
                if (parComparador.Key == parAComparar.Key)
                {
                    continue;

                }
                else
                {
                    foreach (punto p in parComparador.Value)
                    {
                        bool encontro = false;
                        foreach (punto p2 in parAComparar.Value)
                        {
                            if (p.fecha == p2.fecha)
                            {
                                encontro = true;
                                break;
                            }
                        }
                        if (!encontro)
                        {
                            punto nuevoPunto = new punto();
                            nuevoPunto.valor = 0;
                            nuevoPunto.fecha = p.fecha;
                            parAComparar.Value.Add(nuevoPunto);
                        }
                    }
                }
            }
        }

        chartEvolucion.Charts.Clear();

        foreach (KeyValuePair<string, List<punto>> pair in graficos)
        {
            StackedColumnChart grafico = new StackedColumnChart();
            grafico.Legend = pair.Key;
            grafico.LineMarker = new CircleLineMarker(6, grafico.Fill.Color, grafico.Line.Color);
            alpha++;
            grafico.Fill.Color = dameUnColor(ref alpha);
            List<punto> datos = pair.Value;
            datos.Sort();
            foreach (punto dato in datos)
            {
                grafico.Data.Add(new ChartPoint(dato.fecha.ToShortDateString(), dato.valor));
            }
            chartEvolucion.Charts.Add(grafico);
        }


        chartEvolucion.Legend.Width = 40;
        chartEvolucion.RedrawChart();

    }

    private static Color dameUnColor(ref int alpha)
    {
        Color result;
        switch (alpha)
        {
            case 1:
                result = Color.Aqua;
                break;
            case 2:
                result = Color.Red;
                break;
            case 3:
                result = Color.Yellow;
                break;
            case 4:
                result = Color.Green;
                break;
            case 5:
                result = Color.Honeydew;
                break;
            case 6:
                result = Color.BlueViolet;
                break;
            case 7:
                result = Color.Chocolate;
                break;
            case 8:
                result = Color.Coral;
                break;
            case 9:
                result = Color.DeepSkyBlue;
                break;
            default:
                result = Color.IndianRed;
                alpha = 0;
                break;

        }
        return result;
    }

    private void llenarGraficoDePeso(List<Clasificacion> clasificaciones)
    {
        LineChart chart1 = new LineChart();
        chart1.Line.Color = Color.Red;
        chart1.Fill.Color = Color.Red;
        chart1.LineMarker = new DiamondLineMarker(8, Color.Green, Color.Yellow);
        chart1.Legend = "Peso (g)";

        foreach (Clasificacion clas in clasificaciones)
        {
            chart1.Data.Add(new ChartPoint(clas.fecha.ToShortDateString(), (float)clas.peso));
        }


        charPeso.Charts.Clear();
        charPeso.Charts.Add(chart1);

        charPeso.Legend.Width = 0;
        ConfigureColors(charPeso);
        charPeso.RedrawChart();

    }

    private void ConfigureColors(ChartControl ChartControlToSetup)
    {
        ChartControlToSetup.Background.Color = Color.FromArgb(75, Color.SteelBlue);
        ChartControlToSetup.Background.Type = InteriorType.LinearGradient;
        ChartControlToSetup.Background.ForeColor = Color.SteelBlue;
        ChartControlToSetup.Background.EndPoint = new Point(500, 350);
        ChartControlToSetup.Legend.Position = LegendPosition.Bottom;


        ChartControlToSetup.YAxisFont.ForeColor = Color.SteelBlue;
        ChartControlToSetup.XAxisFont.ForeColor = Color.SteelBlue;

        ChartControlToSetup.ChartTitle.ForeColor = Color.White;

        ChartControlToSetup.Border.Color = Color.SteelBlue;
        ChartControlToSetup.BorderStyle = BorderStyle.Ridge;

    }

    private void llenarGraficoDeTamanio(List<Clasificacion> clasificaciones)
    {

        LineChart chart1 = new LineChart();
        chart1.Line.Color = Color.Red;
        chart1.Fill.Color = Color.Red;
        chart1.LineMarker = new DiamondLineMarker(8, Color.Green, Color.Yellow);
        chart1.Legend = "Tamaño (cm)";

        foreach (Clasificacion clas in clasificaciones)
        {
            chart1.Data.Add(new ChartPoint(clas.fecha.ToShortDateString(), (float)clas.tamanio));
        }

        charTamanioPez.Legend.Width = 0;
        charTamanioPez.Charts.Clear();
        charTamanioPez.Charts.Add(chart1);
        ConfigureColors(charTamanioPez);
        charTamanioPez.RedrawChart();


    }

    private Boolean seleccionarClasificacion(int p)
    {
        Clasificacion clasif = new Clasificacion();
        if (clasif.obtener(p))
        {
            lblCantEstanque.Text = clasif.totalEnEstanque.ToString();
            lblCapacidad.Text = this.estanque.capacidad.ToString();
            if (clasif.claseDeLote != null)
            {
                lblClaseDeLote.Text = clasif.claseDeLote.Descripcion;
            }
            else
            {
                lblClaseDeLote.Text = "";

            }
            lblCodigoEstanque.Text = this.estanque.idEstanque.ToString();
            lblDescripcionEstanque.Text = this.estanque.descripcion;
            lblUbicacion.Text = this.estanque.ubicacion;
            lblTamanio.Text = clasif.tamanio.ToString();
            lblPesoMedio.Text = clasif.peso.ToString();
            if (clasif.especie != null)
            {
                lblEspecie.Text = clasif.especie.ToString();
            }
            else
            {
                lblEspecie.Text = "";
            }
            if (clasif.estanqueOrigen != null)
            {
                lblEstanqueOrigen.Text = clasif.estanqueOrigen.ToString();
            }
            else
            {
                lblEstanqueOrigen.Text = "Sin dato de estanque. Esto ocurre solo en el primer ingreso de peces o el último movimiento al vaciar el estanque.";
            }

            if (clasif.cantidadEntrante > 0)
            {
                lblDescripcionEntrante.Text = "Cantidad entrante:";
                lblCantidadEntrante.Text = clasif.cantidadEntrante.ToString();
            }
            else
            {
                lblDescripcionEntrante.Text = "Cantidad saliente:";
                lblCantidadEntrante.Text = Convert.ToString(clasif.cantidadEntrante * -1);
            }

            lblTamanioMuestra.Text = clasif.TamanioMuestra.ToString();
            lblTipoEstanque.Text = this.estanque.tipoDeEstanqueDesc;

            if (estanque.urlCrockis != null)
            {
                imgCrokis.Visible = true;

                imgCrokis.ImageUrl = "~/Images/" + estanque.urlCrockis;
            }
            else
            {
                imgCrokis.Visible = false;
            }

            graficarDistribucionDeLotes(clasif);

            if (clasif.idPlanClasificacion > 0)
            {
                idPlan = clasif.idPlanClasificacion;
                PlanDeClasificacion plan = PlanDeClasificacion.getManager.GetOneByPrimaryKey(clasif.idPlanClasificacion);
                if (plan != null)
                {
                    chartTamanoVsPlan.Visible = true;
                    charPlanDias.Visible = true;
                    Button2.Visible = true;
                    lblMensaje.Text = "Gráficos del correspondientes al plan del estanque: " +
                                      plan.Estanque.descripcionEnLinea;
                    mostrarGraficosDePlanificaciones(plan);

                }
                else
                {
                    lblMensaje.Text = "Ha ocurrido un error inesperado al obtener la información del plan, por favor vuelva a intentar más tarde.";
                }
            }
            else
            {
                idPlan = 0;
                chartTamanoVsPlan.Visible = false;
                charPlanDias.Visible = false;
                Button2.Visible = false;
                lblMensaje.Text = "Este estado de clasificación no tiene un plan asociado, seleccione otra clasificación en el combo de arriba que este asociada a un plan para ver esta información.";
            }
            return true;
        }
        else
        {
            Functions.MessageBox("No se pudo obtener la clasificación.", this);
            multiPrincipal.SetActiveView(viewFiltros);
            return false;
        }



    }

    private Int32 idPlan
    {
        get
        {
            return Convert.ToInt32(ViewState["idPlan"]);
        }
        set
        {
            ViewState["idPlan"] = value;
        }

    }

    private void mostrarGraficosDePlanificaciones(PlanDeClasificacion plan)
    {
        //Grafico de tamaño obtenido vs planeado.
        LineChart chartTamañoPlaneado = new LineChart();
        chartTamañoPlaneado.Line.Color = Color.Red;
        chartTamañoPlaneado.Fill.Color = Color.Red;
        chartTamañoPlaneado.LineMarker = new DiamondLineMarker(8, Color.Red, Color.Yellow);
        chartTamañoPlaneado.Legend = "Tamaño planeado";

        LineChart chartTamanioObtenido = new LineChart();
        chartTamanioObtenido.Line.Color = Color.Blue;
        chartTamanioObtenido.Fill.Color = Color.Blue;
        chartTamanioObtenido.LineMarker = new DiamondLineMarker(8, Color.Blue, Color.Yellow);
        chartTamanioObtenido.Legend = "Tamaño obtenido";

        LineChart chartPlan = new LineChart();
        chartPlan.Line.Color = Color.Red;
        chartPlan.Fill.Color = Color.Red;
        chartPlan.LineMarker = new DiamondLineMarker(8, Color.Green, Color.Yellow);
        chartPlan.Legend = "Desviación en la ejecución del plan (días)";


        foreach (CronogramaDeClasificacion det in plan.DetallePlanClasificacion)
        {
            if (det.TamanioObtenido != 0)
            {
                chartTamañoPlaneado.Data.Add(new ChartPoint(det.Fecha.ToShortDateString(),
                                            (float)det.TamanioEsperado));

                chartTamanioObtenido.Data.Add(new ChartPoint(det.Fecha.ToShortDateString(),
                                            (float)det.TamanioObtenido));
                if (det.Realizado == "+")
                {
                    chartPlan.Data.Add(new ChartPoint(det.Fecha.ToShortDateString(), Math.Abs((float)det.DiasDesfazados)));
                }
                else
                {
                    chartPlan.Data.Add(new ChartPoint(det.Fecha.ToShortDateString(), (float)det.DiasDesfazados));
                }
            }

        }


        chartTamanoVsPlan.Charts.Clear();
        chartTamanoVsPlan.Charts.Add(chartTamañoPlaneado);
        chartTamanoVsPlan.Charts.Add(chartTamanioObtenido);

        ConfigureColors(chartTamanoVsPlan);
        chartTamanoVsPlan.Legend.Width = 40;

        chartTamanoVsPlan.RedrawChart();

        charPlanDias.Charts.Clear();
        charPlanDias.Charts.Add(chartPlan);
        ConfigureColors(charPlanDias);
        charPlanDias.Legend.Width = 40;

        charPlanDias.RedrawChart();

    }

    private void graficarDistribucionDeLotes(Clasificacion clasif)
    {
        charDistribucion.Background.Color = Color.FromArgb(75, Color.SteelBlue);
        charDistribucion.Background.Type = InteriorType.LinearGradient;
        charDistribucion.Background.ForeColor = Color.SteelBlue;
        charDistribucion.Background.EndPoint = new Point(500, 568);
        charDistribucion.Legend.Position = LegendPosition.Bottom;
        charDistribucion.GridLines = WebChart.GridLines.None;
        charDistribucion.ChartTitle.Text = "Distribución de lotes de ovas.";
        charDistribucion.ChartTitle.ForeColor = Color.Black;
        charDistribucion.Border.Color = Color.SteelBlue;
        charDistribucion.BorderStyle = BorderStyle.Ridge;

        PieChart chart = new PieChart();
        chart.ShowLegend = true;
        chart.Shadow.Color = Color.Gray;
        chart.Shadow.Visible = true;
        chart.ShowLineMarkers = true;

        chart.Legend = "Distribución de lote de ovas.";

        foreach (detalleClasificacion det in clasif.detalle)
        {
            chart.Data.Add(new ChartPoint(
                det.loteDeOva.Codigo + " " +
                (Math.Round(det.proporcion * 100)).ToString() + "%",
                (float)det.proporcion * 100));
        }


        charDistribucion.Charts.Add(chart);
        charDistribucion.RedrawChart();
    }

    private void llenarComboClasificaciones()
    {
        cboClasificaciones.DataSource = Clasificacion.obtenerTodas(estanque.idEstanque, fechaDesde, fechaHasta);
        cboClasificaciones.DataTextField = "descripcion";
        cboClasificaciones.DataValueField = "idclasificacion";
        cboClasificaciones.DataBind();
        cboClasificaciones.SelectedIndex = cboClasificaciones.Items.Count - 1;
    }

    protected void Button1_Click(object sender, EventArgs e)
    {
        Response.Redirect("consultarSeguimientoDeEstanque.aspx");
    }
    protected void Button2_Click(object sender, EventArgs e)
    {
        visorDeReportes vr = new visorDeReportes();
        vr.archivoReporte = new rptPlanDeClasificacion();
        vr.paradescript = "";
        vr.paravalor = "";
        vr.selectionFormula = "{PLANESCLASIFICACION.IDPLANCLASIFICACION}=" + this.idPlan;
        vr.verReporte(Page);
        modoReporte();
    }
}
